/**
 * @(#)ReserveInstallServiceImpl.java 2017年9月25日
 * Copyright(C) 2017 ZHEXIN IT CO.,LTD. All rights reserved.
 */
package org.jsbd.boss.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.jsbd.boss.common.redis.RedisClient;
import org.jsbd.boss.dao.IAddReserveConfigDAO;
import org.jsbd.boss.dao.IAddReserveRecordDAO;
import org.jsbd.boss.dao.IAddUserRecordDAO;
import org.jsbd.boss.domian.channel.AddReserveConfigVo;
import org.jsbd.boss.domian.channel.AddReserveRecordVo;
import org.jsbd.boss.service.IReserveAddService;
import org.jsbd.boss.util.CacheKey;
import org.jsbd.boss.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * 预留安装新增用户收集
 * 
 * @author <a href="mailto:xupengcheng@zhexinit.com" >徐鹏程</a>
 * @version 1.0.0
 */
@Service("reserveAddService")
public class ReserveAddServiceImpl implements IReserveAddService {
	public static final Logger LOGGER = LoggerFactory.getLogger(ReserveAddServiceImpl.class);

	@Resource
	private IAddReserveConfigDAO addReserveConfigDAO;
	@Resource
	private IAddReserveRecordDAO addReserveRecordDAO;
	@Resource
	private IAddUserRecordDAO addUserRecordDAO;

	@Resource
	private CacheParamManager cacheParamManager;

	private int MAXSIZE = 20;

	@Resource
	private RedisClient redisClient;

	private int getApkCount(String mark, List<AddReserveRecordVo> countList) {
		for (AddReserveRecordVo record : countList) {
			Integer total = record.getTotal();
			String apk = record.getMark();
			if (mark.equals(apk)) {
				return total;
			}
		}
		return 0;
	}

	@Override
	public void initReserveAddUserData() {
		// 1、查询当天预安装数据
		// 2、查询预安装用户比例
		// 3、将数据插入到之后的配置天内
		List<AddReserveConfigVo> configList = addReserveConfigDAO.selectUsefulConfigList(null);
		List<AddReserveRecordVo> countList = addReserveRecordDAO.selectCountOfMark(null);
		for (AddReserveConfigVo apkConfig : configList) {
			Integer rate = apkConfig.getAddRate();
			String mark = apkConfig.getMark().trim();
			Integer day = apkConfig.getAddDay();
			String lockKey = CacheKey.R_A_U_LOCK + mark + day;
			if (redisClient.evalSetNx(lockKey, 120)) {
				int total = getApkCount(mark, countList) * rate / 100;
				// 已经导入的记录
				String recordKey = CacheKey.RESERVE_USER_RECORD + DateUtil.getDaysOfTime();
				String fieldKey = mark + day;
				int execCount = 0;
				String hasCheckCount = redisClient.evalHget(recordKey, fieldKey);
				if (hasCheckCount != null) {
					execCount = Integer.parseInt(hasCheckCount);
				}
				total = total - execCount;
				int size = 0;
				if (total > 0) {
					List<AddReserveRecordVo> records = new ArrayList<AddReserveRecordVo>();
					try {
						String dayStr = DateUtil.getFutureSomeDay(day);
						Integer rd = Integer.parseInt(dayStr);
						while (total > 0) {
							AddReserveRecordVo recordVo = getAddReserveRecordVo(mark);
							if (recordVo != null) {
								recordVo.setRd(rd);
								records.add(recordVo);
								size++;
								total--;
							} else {
								break;
							}
						}
					} catch (Exception e) {
						LOGGER.error("initReserveAddUserData", e);
					}
					addUserRecordDAO.batchInsertRecord(records);
					redisClient.evalHincrby(recordKey, fieldKey, size, DateUtil.leftTimeToMidNight() / 1000);
				}
				redisClient.remove(lockKey);
			}

		}
	}

	private AddReserveRecordVo getAddReserveRecordVo(String mark) {
		String currDay = DateUtil.getCurrentDateStr();
		String userListKey = CacheKey.RESERVE_USER_LIST + mark + currDay;
		AddReserveRecordVo user = (AddReserveRecordVo) redisClient.pollFromQueue(userListKey);
		if (user == null) {
			if (redisClient.evalSetNx(userListKey + "_LOCK", 120)) {
				AddReserveRecordVo record = new AddReserveRecordVo();
				record.setMark(mark);
				Object maxCacheLength = cacheParamManager.getParamValue(CacheKey.USER_CACHE_LENGTH);
				if (maxCacheLength != null) {
					MAXSIZE = Integer.parseInt(maxCacheLength.toString());
				}
				record.setLength(MAXSIZE);
				Integer rd = Integer.parseInt(currDay);
				record.setRd(rd);
				List<AddReserveRecordVo> userList = addReserveRecordDAO.selectRecordList(record);
				if (userList.size() > 0) {
					Iterator<AddReserveRecordVo> userIterator = userList.iterator();
					while (userIterator.hasNext()) {
						userIterator.next().setRd(rd);
					}
					addReserveRecordDAO.batchUpdateRecord(userList);
					redisClient.putToQueue(userListKey, userList.toArray(new AddReserveRecordVo[0]));
					redisClient.expire(userListKey, DateUtil.leftTimeToMidNight());
					user = (AddReserveRecordVo) redisClient.pollFromQueue(userListKey);
				}
				redisClient.remove(userListKey + "_LOCK");
			}
		}
		return user;
	}
}
